import re
from django import http
from meiduo_mall import settings
from django.contrib.auth import login
# from meiduo_mall.settings import dev
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from QQLoginTool.QQtool import OAuthQQ
from django_redis import get_redis_connection

from utils.response_code import RETCODE
from .models import QAuthQQUser, SinaUser
from apps.oauth.utils import generate_eccess_token, check_access_token, sina_eccess_token, check_sina_token
# from . import constants
from apps.users.models import User
from libs import sinaweibopy3
import logging

logger = logging.getLogger('django')


class OAuthQQView(View):
    """
    提供QQ登录页面网址
    https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=xxx&redirect_uri=xxx&state=xxx
    """

    def get(self, request):
        # 回转路径
        next_url = request.GET.get('next')
        # qq登陆路径
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=next_url)

        login_url = oauth.get_qq_url()

        return http.JsonResponse({
            'code': RETCODE.OK,
            'errmsg': 'ok',
            'login_url': login_url
        })


class QQURLView(View):
    # qq回调处理
    def get(self, request):
        # 接受参数
        code = request.GET.get('code')
        state = request.GET.get('state')
        # 验证参数
        if not all([code, state]):
            return http.JsonResponse({'code': RETCODE.OPENIDERR, 'errmsg': '认证错误'})
        # qq认证
        oauth = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            client_secret=settings.QQ_CLIENT_SECRET,
            redirect_uri=settings.QQ_REDIRECT_URI,
            state=state
        )
        # 获取token和openid
        token = oauth.get_access_token(code)
        openid = oauth.get_open_id(token)

        # 判断用户是否已经登陆
        try:
            qquser = QAuthQQUser.objects.get(openid=openid)
        except:
            # 没有跳转到用户绑定页面
            access_token = generate_eccess_token(openid)

            return render(request, 'oauth_callback.html', context={'access_token': access_token})
        else:
            # 有跳转首页
            qq_user = qquser.user

            login(request, qq_user)

            response = redirect(reverse('contents:index'))
            response.set_cookie('username', qq_user.username, max_age=3600 * 24)

            return response

    def post(self, request):
        # 接收参数
        mobile = request.POST.get('mobile')
        password = request.POST.get('pwd')
        sms_client = request.POST.get('sms_code')
        access_token = request.POST.get('access_token')

        # 校验参数
        if not all([mobile, password, sms_client]):
            return http.JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '缺少参数'})
        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('请输入正确的手机号码')
        # 判断密码是否合格
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseBadRequest('请输入8-20位的密码')
        # 验证短信码
        conn = get_redis_connection('code')
        sms_server = conn.get('sms_%s' % mobile)
        sms_server = sms_server.decode()

        if sms_server is None:
            return http.JsonResponse({'code': RETCODE.SMSCODERR, 'errmsg': '验证码过期'})
        if sms_server != sms_client:
            return http.JsonResponse({'code': RETCODE.SMSCODERR, 'errmsg': '验证码错误'})

        openid = check_access_token(access_token)
        if not openid:
            return render(request, 'oauth_callback.html', {'openid_errmsg': '无效的openid'})

        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            user = User.objects.create_user(
                username=mobile,
                password=password,
                mobile=mobile
            )
        else:
            if not user.check_password(password):
                return render(request, 'oauth_callback.html', {'account_errmsg': '用户名或密码错误'})

        try:
            QAuthQQUser.objects.create(openid=openid, user=user)
        except:
            return render(request, 'oauth_callback.html', {'qqlogin_errmsg': 'qq登录失败'})

        login(request, user)
        next = request.GET.get('state')
        response = redirect(next)

        response.set_cookie('username', user.username, max_age=3600 * 24)

        return response


class SinaView(View):
    def get(self, request):
        # sina路径
        oauth = sinaweibopy3.APIClient(
            app_key=settings.App_Key,
            app_secret=settings.Sina_App_Secret,
            redirect_uri=settings.Sina_REDIRECT_URL
        )

        login_url = oauth.get_authorize_url()
        return http.JsonResponse({
            'code': RETCODE.OK,
            'errmsg': 'ok',
            'login_url': login_url
        })


class SinaURLView(View):
    def get(self, request):

        # 接受参数
        code = request.GET.get('code')
        # 验证参数
        if code is None:
            return http.JsonResponse({'code': RETCODE.OPENIDERR, 'errmsg': '认证错误'})

        # sina认证
        sina = sinaweibopy3.APIClient(
            app_key=settings.App_Key,
            app_secret=settings.Sina_App_Secret,
            redirect_uri=settings.Sina_REDIRECT_URL
        )
        # 找到uid
        result = sina.request_access_token(code)
        # token = result.access_token
        uid = result.uid

        # 判断用户是否已经登陆
        try:
            sinauser = SinaUser.objects.get(uid=uid)
        except:
            # 没有跳转到用户绑定页面
            access_token = sina_eccess_token(uid)

            return render(request, 'oauth_callback.html', context={'access_token': access_token})
        else:
            # 有跳转首页
            sina_user = sinauser.user

            login(request, sina_user)

            response = redirect(reverse('contents:index'))
            response.set_cookie('username', sina_user.username, max_age=3600 * 24)

            return response

    def post(self, request):
        # 接受参数
        mobile = request.POST.get('mobile')
        password = request.POST.get('pwd')
        sms_client = request.POST.get('sms_code')

        # 校验参数
        if not all([mobile, password, sms_client]):
            return http.HttpResponseBadRequest('参数不全')
        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('请输入正确的手机号码')
        # 判断密码是否合格
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseBadRequest('请输入8-20位的密码')
        # 验证短信码
        conn = get_redis_connection('code')
        sms_server = conn.get('sms_%s' % mobile)
        sms_server = sms_server.decode()

        if sms_server is None:
            return http.JsonResponse({'code': RETCODE.SMSCODERR, 'errmsg': '验证码过期'})
        if sms_server != sms_client:
            return http.JsonResponse({'code': RETCODE.SMSCODERR, 'errmsg': '验证码错误'})

        access_token = request.POST.get('access_token')
        uid = check_sina_token(access_token)

        if not uid:
            return http.HttpResponseBadRequest("认证失效")

        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            user = User.objects.create_user(
                username=mobile,
                password=password,
                mobile=mobile
            )
        else:
            if not user.check_password(password):
                return render(request, 'oauth_callback.html', {'account_errmsg': '用户名或密码错误'})

        try:
            SinaUser.objects.create(uid=uid, user=user)
        except:
            return render(request, 'oauth_callback.html', {'sinalogin_errmsg': 'sina登录失败'})

        login(request, user)
        response = redirect(reverse('contents:index'))

        response.set_cookie('username', user.username, max_age=3600 * 24)

        return response
